package com.dolphin.common.expr.emus;

import lombok.Getter;

import java.util.Calendar;
import java.util.Date;

/**
 * @author shida
 */

@Getter
public enum WindowUnitEnum implements WindowUnitFunction {

    SEC("SEC", "秒") {
        @Override
        public Long getStartDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(new Date());
            calendar.add(Calendar.SECOND, (windowLength - 1) * -1);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Long getEndDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.SECOND, windowLength);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Integer getSecond() {
            return 1;
        }
    },
    MIN("MIN", "分钟") {
        @Override
        public Long getStartDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(new Date());
            calendar.add(Calendar.MINUTE, (windowLength - 1) * -1);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Long getEndDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.MINUTE, windowLength);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Integer getSecond() {
            return 60;
        }
    },
    HOUR("HOUR", "小时") {
        @Override
        public Long getStartDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.HOUR, (windowLength - 1) * -1);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Long getEndDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.HOUR, windowLength);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Integer getSecond() {
            return 3600;
        }
    },
    DAY("DAY", "天") {
        @Override
        public Long getStartDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.DATE, (windowLength - 1) * -1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Long getEndDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.DATE, windowLength);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Integer getSecond() {
            return 24 * 3600;
        }
    },
    WEEK("WEEK", "周") {
        @Override
        public Long getStartDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DATE, (windowLength - 1) * -7);

            calendar.getTime();
            calendar.setFirstDayOfWeek(Calendar.MONDAY);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Long getEndDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.DATE, windowLength * 7);
            calendar.setFirstDayOfWeek(Calendar.MONDAY);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Integer getSecond() {
            return 7 * 24 * 3600;
        }
    },
    MONTH("MONTH", "月") {
        @Override
        public Long getStartDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.MONTH, (windowLength - 1) * -1);

            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Long getEndDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.MONTH, windowLength);

            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Integer getSecond() {
            return 30 * 24 * 3600;
        }
    }, YEAR("YEAR", "年") {
        @Override
        public Long getStartDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.YEAR, (windowLength - 1) * -1);

            calendar.set(Calendar.MONTH, 1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Long getEndDateByNature(int windowLength, Date date) {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(date);
            calendar.add(Calendar.YEAR, windowLength);

            calendar.set(Calendar.MONTH, 1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            return calendar.getTimeInMillis();
        }

        @Override
        public Integer getSecond() {
            return 365 * 24 * 3600;
        }
    };

    private String code;
    private String desc;

    WindowUnitEnum(String code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public static WindowUnitEnum getByCode(String code) {
        for (WindowUnitEnum windowUnitEnum : WindowUnitEnum.values()) {
            if (windowUnitEnum.getCode().equals(code)) {
                return windowUnitEnum;
            }
        }
        return null;
    }
}
